#ifndef PKB_H
#define PKB_H
#include "Parser.h"
#include "StmtTable.h"
#include "Next.h"
#include "NextBip.h"
#include "PCall.h"
#include <algorithm>

class PKB{
private:
	AST ast;
	VarTable varTable;
	ProcTable procTable;
	ConstTable constTable;
	Modifies modifies;
	Uses uses;
	Calls calls;
	PatternTable patternTable;
	LoopTable loopTable;
	Next next;
	NextBip nextBip;
	StmtTable sTable;
	StmtLstTable stmtLstTable;
	PlusTable plusTable;
	MinusTable minusTable;
	TimesTable timesTable;
	vector<int> sortedCall;
	Contains contains;
	int TotalLineNum;
	//affect Bip
	vector<vector<int>> extendProcedure;
	vector<int> extendRoot;
	//-----------------------

	vector<pair<int,int>> fullModifiesTable; // Modifies table built by Parser cannot be used by Query Evaluator, fullModifiesTable can be used as Modifies Table
	vector<int> fullModifiesMap;
	vector<pair<int,int>> fullUsesTable;     // Uses table built by Parser cannot be used by Query Evaluator, fullUsesTable can be used as Uses Table
	vector<vector<int>> fullUsesMatrix;

	vector<vector<int>> PModifiesTableV1;  //deal with Modifies(p,_) V1,V2 stands for two versions of different data structure
	vector<vector<int>> PUsesTableV1;    //pair lineNum, variable 
	vector<pair<int,int>> PModifiesTableV2;
	vector<pair<int,int>> PUsesTableV2;   //Triple lineNum, p, variable

	vector<pair<int, int>> FollowsList;
	vector<vector<int>> FollowsMatrix;

	vector<pair<int, int>> ParentList;
	vector<vector<int>> ParentMatrix;

	vector<vector<int>>	FollowsStarMatrix;
	vector<pair<int, int>> FollowsStarList;
	
	vector<vector<int>> ParentStarMatrix;
	vector<pair<int, int>> ParentStarList;
	
	vector<pair<int, int>> NextList;
	vector<vector<int>> NextMatrix;
	
	vector<pair<int,int>> NextStarList;
	vector<vector<int>> NextStarMatrix;

	vector<pair<int, int>> NextBipList;
	vector<vector<int>> NextBipMatrix;

	vector<pair<int, int>> NextBipStarList;
	vector<vector<int>> NextBipStarMatrix;

	vector<pair<int,int>> CallsList;

	vector<pair<int,int>> CallsStarList; 

	//Affects
	vector<pair<int, int>> AffectsList;
	vector<vector<int>> AffectsMatrix;

	//Affects*
	vector<pair<int, int>> AffectsStarList;
	vector<vector<int>> AffectsStarMatrix;
public:
	PKB();
	PKB(Parser*);
	AST getAST();
	VarTable getVarTable();
	ProcTable getProcTable();
	ConstTable getConstTable();
	Modifies getModifies();
	Uses getUses();
	Calls getCalls();
	PatternTable getPatternTable();
	LoopTable getLoops();
	StmtLstTable getStmtLstTable();
	PlusTable getPlusTable();
	MinusTable getMinusTable();
	TimesTable getTimesTable();
	Contains getContains();
	int getTotalLineNum();

	// Follows
	vector<pair<int, int>> getFollowsList();
	vector<vector<int>> getFollowsMatrix();

	// Parent
	vector<pair<int, int>> getParentList();
	vector<vector<int>> getParentMatrix();

	// Follows*
	void setFollowsStarList(vector<pair<int, int>>);
	vector<pair<int, int>> getFollowsStarList();
	void setFollowsStarMatrix(vector<vector<int>>);
	vector<vector<int>> getFollowsStarMatrix();

	// Parent*
	void setParentStarList(vector<pair<int, int>>);
	vector<pair<int, int>> getParentStarList();
	void setParentStarMatrix(vector<vector<int>>);
	vector<vector<int>> getParentStarMatrix();

	// Modifies
	void setFullModifiesTable(vector<pair<int,int>>);
	vector<pair<int,int>> getFullModifiesTable();
	void setFullModifiesMap(vector<int>);
	vector<int> getFullModifiesMap();

	// Uses
	void setFullUsesTable(vector<pair<int,int>>);
	vector<pair<int,int>> getFullUsesTable();
	void setFullUsesMatrix(vector<vector<int>>);
	vector<vector<int>> getFullUsesMatrix();

	// Procedure Modifies
	void setPModifiesTableV1(vector<vector<int>>);
	vector<vector<int>> getPModifiesTableV1();
	
	void setPModifiesTableV2(vector<pair<int,int>>);
	vector<pair<int,int>> getPModifiesTableV2();

	// Procedure Uses
	void setPUsesTableV1(vector<vector<int>>);
	vector<vector<int>> getPUsesTableV1();

	void setPUsesTableV2(vector<pair<int,int>>);
	vector<pair<int,int>> getPUsesTableV2();

	// Next
	void setNext(Next);
	Next getNext();
	
	vector<pair<int, int>> getNextList();
	void setNextMatrix(vector<vector<int>>);
	vector<vector<int>> getNextMatrix();
	
	// Next*
	void setNextStarList(vector<pair<int,int>>);
	vector<pair<int,int>> getNextStarList();
	void setNextStarMatrix(vector<vector<int>>);
	vector<vector<int>> getNextStarMatrix();
	
	//NextBip
	void setNextBip(NextBip);
	void setProcTable(ProcTable);
	NextBip getNextBip();

	vector<pair<int,int>> getNextBipList();
	void setNextBipMatrix(vector<vector<int>>);
	vector<vector<int>> getNextBipMatrix();

	//NextBip*
	void setNextBipStarList(vector<pair<int,int>>);
	vector<pair<int,int>> getNextBipStarList();
	void setNextBipStarMatrix(vector<vector<int>>);
	vector<vector<int>> getNextBipStarMatrix();

	//Call
	vector<pair<int,int>> getCallsList();
	vector<int> getCalleeList();

	// Call*
	void setCallsStarList(vector<pair<int,int>>);
	vector<pair<int,int>> getCallsStarList();

	// Statement table
	void setStmtTable(StmtTable);
	StmtTable getStmtTable();

	// Affect Bip
	void setAffectBipSimpleText(vector<vector<int>> textList,vector<int> rootOfList);
	vector<vector<int>> getExtendProcedure();
	vector<int> getExtendRoot();

	// Affects
	void setAffectsMatrix(vector<vector<int>>);
	void setAffectsList(vector<pair<int,int>>);
	vector<vector<int>> getAffectsMatrix();
	vector<pair<int,int>> getAffectsList();

	// Affects*
	void setAffectsStarMatrix(vector<vector<int>>);
	void setAffectsStarList(vector<pair<int,int>>);
	vector<vector<int>> getAffectsStarMatrix();
	vector<pair<int,int>> getAffectsStarList(); 

	void setSortedCall(vector<int>);
    vector<int> getSortedCall();
	// ContainsStar
	void setContains(Contains);
};
#endif